package cn.gson.financial.controller;

import cn.gson.financial.annotation.IgnoresLogin;
import cn.gson.financial.annotation.ValidWhiteNameList;
import cn.gson.financial.base.BaseCrudController;
import cn.gson.financial.kernel.controller.JsonResult;
import cn.gson.financial.kernel.model.entity.AccountSets;
import cn.gson.financial.kernel.model.entity.UserAccountSets;
import cn.gson.financial.kernel.model.entity.Voucher;
import cn.gson.financial.kernel.model.mapper.UserAccountSetsMapper;
import cn.gson.financial.kernel.model.vo.AddUserRoleVo;
import cn.gson.financial.kernel.model.vo.UserVo;
import cn.gson.financial.kernel.service.AccountSetsService;
import cn.gson.financial.kernel.service.UserAccountSetsService;
import cn.gson.financial.kernel.service.UserService;
import cn.gson.financial.kernel.service.VoucherService;
import cn.gson.financial.kernel.utils.RedisCacheManager;
import cn.gson.financial.kernel.utils.RedisUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.base.CharMatcher;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


@RestController
@RequestMapping("/account-sets")
@Slf4j
public class AccountSetsController extends BaseCrudController<AccountSetsService, AccountSets> {

    @Autowired
    private UserAccountSetsService userAccountSetsService;
    @Autowired
    private VoucherService voucherService;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RedisCacheManager redisCacheManager;
    @Autowired
    private UserAccountSetsMapper userAccountSetsMapper;

    //重置账套
    @PostMapping("/resetting")
    public JsonResult resetting(@RequestBody AccountSets entity){
        session.removeAttribute(this.currentUser.getMobile());
        Long id = new Long((long)entity.getId());
        JsonResult rs = super.delete(id);
        userAccountSetsService.deletAllVoucher(entity.getId());
        try {
            entity.setCurrentAccountDate(entity.getEnableDate());
            entity.setCreatorId(this.currentUser.getId());
            service.save(entity);
            //更新 Session 中的用户信息
            UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
            redisUtil.setAttribute(userVo,session);

            return JsonResult.successful("账套重置成功!");
        } catch (Exception e) {
            log.error("账套重置失败！", e);
            return JsonResult.failure("账套重置失败!");
        }

    }
    /**
     * 检查登录状获取态和并返回登录信息
     *
     * @param user
     * @return
     */
    @IgnoresLogin
    @GetMapping("/loginInit")
    @ValidWhiteNameList
    public JsonResult init(@SessionAttribute(value = "user", required = false) UserVo user) {
        if (user == null) {
            return JsonResult.failure();
        }
        session.removeAttribute(this.currentUser.getMobile());
        UserVo userVo = this.userService.getUserVo(this.currentUser.getId());//this.currentUser.getId()是user表中的主键id===32
        //更新 Session 中的用户信息
        UserVo userVo1 = redisUtil.setAttribute(userVo, session);

        LambdaQueryWrapper<UserAccountSets> uaqw = Wrappers.lambdaQuery();
        uaqw.eq(UserAccountSets::getUserId, this.currentUser.getId());
        uaqw.eq(UserAccountSets::getRoleType, "admin");
        uaqw.eq(UserAccountSets::getAccountSetsId, 0);
        Integer integer = userAccountSetsMapper.selectCount(uaqw);
        if (integer>0){
            userVo1.setIsAdmin(true);
        }
        return JsonResult.successful(userVo1);
    }

    @PostMapping("/updateSession")
    public JsonResult updateSession(){
        //更新 Session 中的用户信息
        UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
        redisUtil.setAttribute(userVo,session);
        return JsonResult.successful();
    }

    @Override
    public JsonResult list(Map<String, String> params) {
        // 1.从中间表查出当前用户的所有账套
        LambdaQueryWrapper<UserAccountSets> uasQw = Wrappers.lambdaQuery();
        uasQw.eq(UserAccountSets::getUserId, this.currentUser.getId());
        List<UserAccountSets> list = userAccountSetsService.list(uasQw);

        if (list.size() > 0) {
            // 2.获取账套信息
            QueryWrapper<AccountSets> asQw = Wrappers.query();
            IntStream intStream = list.stream().mapToInt(UserAccountSets::getAccountSetsId);
            asQw.in("id", intStream.boxed().collect(Collectors.toList()));
            asQw.allEq(params);
            this.getPageList(params, userAccountSetsService);

            return JsonResult.successful(this.service.list(asQw));
        }
        return JsonResult.successful();
    }

    @Override
    public JsonResult save(@RequestBody AccountSets entity) {
        System.out.println("start...");
        try {
            entity.setCurrentAccountDate(entity.getEnableDate());
            entity.setCreatorId(this.currentUser.getId());
            Boolean bool = service.save(entity);
            if (bool){
                //更新 Session 中的用户信息
                UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
                redisUtil.setAttribute(userVo,session);

                return JsonResult.successful(entity);
            }else {
                return JsonResult.failure("已存在该单位名称的账套，创建失败");
            }
        } catch (Exception e) {
            log.error("账套创建失败！", e);
            return JsonResult.failure("账套创建失败!");
        }
    }

    @Override
    public JsonResult update(@RequestBody AccountSets entity) {
        JsonResult result = super.update(entity);
        if (result.isSuccess() && entity.getId().equals(this.accountSetsId)) {
            //更新 Session 中的用户信息
            UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
            redisUtil.setAttribute(userVo,session);
        }
        return result;
    }


    @GetMapping("addUser")
    public JsonResult addUser(String mobile, String role) {
        this.service.addUser(this.accountSetsId, mobile, role);
        return JsonResult.successful();
    }

    @GetMapping("updateUserRole")
    public JsonResult updateUserRole(Integer id, String role) {
        this.service.updateUserRole(this.accountSetsId, id, role);
        return JsonResult.successful();
    }

    @GetMapping("addNewUser")
    public JsonResult addNewUser(String mobile, String role, String code, HttpSession session) {
        String scode = (String) session.getAttribute(mobile);
        if (scode == null || !scode.equals(code)) {
            return JsonResult.failure("验证码错误!");
        }
        session.removeAttribute(mobile);
//        this.service.addNewUser(this.accountSetsId, mobile, role);
        return JsonResult.successful();
    }

    @GetMapping("removeUser/{uid}")
    public JsonResult removeUser(@PathVariable Integer uid) {
        this.service.removeUser(this.accountSetsId, uid);
        return JsonResult.successful();
    }

    @PostMapping("identification")
    public JsonResult identification(@RequestParam String code) {
        if (code.equals(this.session.getAttribute(this.currentUser.getMobile()))) {
            this.session.setAttribute(this.currentUser.getMobile() + "_checked", true);
            this.session.removeAttribute(this.currentUser.getMobile());
            return JsonResult.successful();
        }
        return JsonResult.failure("验证码校验失败！");
    }

    /**
     * 更新科目编码设置
     *
     * @param encoding
     * @param newEncoding
     * @return
     */
    @PostMapping("updateEncode")
    public JsonResult updateEncode(@RequestParam String encoding, @RequestParam String newEncoding) {
        if (!encoding.equals(newEncoding)) {
            this.service.updateEncode(this.accountSetsId, encoding, newEncoding);
            //更新 Session 中的用户信息
            UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
            redisUtil.setAttribute(userVo,session);
        }
        return JsonResult.successful();
    }

    @PostMapping("handOver")
    public JsonResult handOver(@RequestParam String code, @RequestParam String mobile) {
        if (this.session.getAttribute(this.currentUser.getMobile() + "_checked") == null) {
            return JsonResult.failure("亲，移交用户信息未确认！");
        }

        if (code.equals(this.session.getAttribute(mobile))) {
            this.service.handOver(this.accountSetsId, this.currentUser.getId(), mobile);
            this.session.removeAttribute(mobile);
            //更新 Session 中的用户信息
            UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
            redisUtil.setAttribute(userVo,session);
            return JsonResult.successful();
        }

        return JsonResult.failure("验证码校验失败！");
    }

    /**
     * 检查账套是否已有凭证
     *
     * @param asid 账套 ID
     * @return
     */
    @GetMapping("checkUse")
    public JsonResult checkUse(@RequestParam Integer asid) {
        LambdaQueryWrapper<Voucher> qw = Wrappers.lambdaQuery();
        qw.eq(Voucher::getAccountSetsId, asid);
        return JsonResult.successful(this.voucherService.count(qw) > 0);
    }

    /**
     * 屏蔽默认的删除操作
     *
     * @param id
     * @return
     */

    @Override
    public JsonResult delete(Long id) {
        return JsonResult.failure();
    }

    /**
     * 带验证码删除
     *
     * @param id
     * @param smsCode
     * @return
     */
    @DeleteMapping("/{id:\\d+}/{smsCode}/{phone}")
    public JsonResult delete(@PathVariable Long id, @PathVariable String smsCode,@PathVariable String phone) {
        if (!smsCode.equals(redisCacheManager.get(phone+"power"))) {
//        if (!smsCode.equals("6666")) {
            return JsonResult.failure("验证码错误！");
        }
        session.removeAttribute(this.currentUser.getMobile());
        JsonResult rs = super.delete(id);
        if (rs.isSuccess()) {
            //更新 Session 中的用户信息
            UserVo userVo = this.userService.getUserVo(this.currentUser.getId());
            redisUtil.setAttribute(userVo,session);
        }
        return rs;
    }
}
